#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <sched.h>

void pclock(char *msg, int pid, clockid_t cid) {
	struct timespec ts;

	if (clock_gettime(cid, &ts) == -1) {
		printf("clock_gettime failed!\n");
		return;
	}
	printf("%stid=[%d]    %4ld.%03ld\n", msg, pid, ts.tv_sec,
	       ts.tv_nsec / 1000000);
}


void* do_something(void *arg) {
	clockid_t cid_thread, cid_self;
	if (0 != pthread_getcpuclockid(pthread_self(), &cid_self)) {
		printf("pthread_getcpuclockid failed!\n");
		return NULL;
	}

	size_t count = *((size_t*) arg);
	int x = 1;

	size_t i = 1;
	for (; i < count; ++i)
		x *= i;

	pclock("Thread CPU time:", pthread_self(), cid_self);

	return NULL;
}

#define THREAD_COUNT 2

int main() {
	size_t count = 10000000000; 
	
	pthread_t thr[THREAD_COUNT];
	int i = 0;
	for (; i < THREAD_COUNT; ++i) {
		if (0 != pthread_create(thr + i, NULL, do_something, &count)) {
			printf("pthread_create failed!\n");
			return 1;
		}
#if 1
		cpu_set_t cpuset;
		CPU_ZERO(&cpuset);
		CPU_SET(0, &cpuset);
		if (0 != pthread_setaffinity_np(thr[i], sizeof(cpu_set_t), &cpuset)) {
			printf("pthread setaffinity_np failed");
			return 1;
		}
#endif
	}

	for (i = 0; i < THREAD_COUNT; ++i)
		if (0 != pthread_join(thr[i], NULL)) {
			printf("pthread_join failed\n");
			return 1;
		}
	
	pclock("Process total CPU time: ", 0, CLOCK_PROCESS_CPUTIME_ID);

	return 0;
}
